﻿using System;
using biz.ritter.javapi.util;
using biz.ritter.javapi.lang;
using Nofs.Net.Common.Interfaces.Domain;
using Nofs.Net.nofs.metadata.interfaces;

namespace Nofs.Net.Domain.Impl
{
    public class CustomStat : IFileObjectStat
    {
        private IFileObjectStat _base;
        private IAttributeAccessor _accessor;
        private Object _obj;
        private IGetterSetterPair _atime;
        private IGetterSetterPair _mtime;
        private IGetterSetterPair _ctime;
        private IGetterSetterPair _mode;
        private IGetterSetterPair _uid;
        private IGetterSetterPair _gid;

        public CustomStat(IFileObjectStat baseObject, IAttributeAccessor accessor, Object obj)
        {
            _base = baseObject;
            _accessor = accessor;
            _obj = obj;
        }

        public IFileObjectStat Inner()
        {
            return _base;
        }

        private IGetterSetterPair ATime() //throws Exception 
        {
            if (_atime == null)
            {
                _atime = _accessor.GetLastAccessTimePair(_obj);
            }
            return _atime;
        }

        private IGetterSetterPair MTime() //throws Exception 
        {
            if (_mtime == null)
            {
                _mtime = _accessor.GetLastModifiedTimePair(_obj);
            }
            return _mtime;
        }

        private IGetterSetterPair CTime() //throws Exception 
        {
            if (_ctime == null)
            {
                _ctime = _accessor.GetCreateTimePair(_obj);
            }
            return _ctime;
        }

        private IGetterSetterPair Mode() //throws Exception 
        {
            if (_mode == null)
            {
                _mode = _accessor.GetModePair(_obj);
            }
            return _mode;
        }

        private IGetterSetterPair UID() //throws Exception 
        {
            if (_uid == null)
            {
                _uid = _accessor.GetUIDPair(_obj);
            }
            return _uid;
        }

        private IGetterSetterPair GID() //throws Exception 
        {
            if (_gid == null)
            {
                _gid = _accessor.GetGIDPair(_obj);
            }
            return _gid;
        }

        public IFileObjectStat Clone() //throws Exception 
        {
            return new CustomStat(_base.Clone(), _accessor, _obj);
        }

        public bool Equals(IFileObjectStat stat)
        {
            return ParentID().equals(stat.ParentID());
        }

        public UUID ParentID()
        {
            return _base.ParentID();
        }

        public String ParentName()
        {
            return _base.ParentName();
        }

        public void SetParentName(String parentName)
        {
            _base.SetParentName(parentName);
        }

        public int getATime() //throws Exception 
        {
            return ATime().GetterExists()
                    ? (int)((Date)ATime().Getter()).getTime()
                    : _base.getATime();
        }

        public long getBlocks()
        {
            return _base.getBlocks();
        }

        public int getCTime() //throws Exception 
        {
            return CTime().GetterExists()
                ? (int)((Date)CTime().Getter()).getTime()
                : _base.getCTime();
        }

        public long getFileSize()
        {
            return _base.getFileSize();
        }

        public int getGID() //throws Exception 
        {
            return GID().GetterExists()
                ? ((Integer)GID().Getter()).intValue()
                : _base.getGID();
        }

        public int getMTime()// //throws Exception 
        {
            return MTime().GetterExists()
                ? (int)((Date)MTime().Getter()).getTime()
                : _base.getMTime();
        }

        public int getMode() //throws Exception 
        {
            return Mode().GetterExists()
                ? ((Integer)Mode().Getter()).intValue()
                : _base.getMode();
        }

        public int getNLink()
        {
            return _base.getNLink();
        }

        public int getRDev()
        {
            return _base.getRDev();
        }

        public int getUID()// //throws Exception
        {
            return UID().GetterExists()
                ? ((Integer)UID().Getter()).intValue()
                : _base.getUID();
        }

        public void setATime(int value) //throws Exception
        {
            if (ATime().SetterExists())
            {
                ATime().Setter(new Date(value));
            }
            _base.setATime(value);
        }

        public void setBlocks(long value)
        {
            _base.setBlocks(value);
        }

        public void setCTime(int value) //throws Exception 
        {
            if (CTime().SetterExists())
            {
                CTime().Setter(new Date(value));
            }
            _base.setCTime(value);
        }

        public void setFileSize(long value)
        {
            _base.setFileSize(value);
        }

        public void setGID(int value) //throws Exception 
        {
            if (GID().SetterExists())
            {
                GID().Setter(value);
            }
            _base.setGID(value);
        }

        public void setMTime(int value) //throws Exception 
        {
            if (MTime().SetterExists())
            {
                MTime().Setter(new Date(value));
            }
            _base.setMTime(value);
        }

        public void setMode(int value)// //throws Exception
        {
            if (Mode().SetterExists())
            {
                Mode().Setter(value);
            }
            _base.setMode(value);
        }

        public void setNLink(int value)
        {
            _base.setNLink(value);
        }

        public void setRDev(int value)
        {
            _base.setRDev(value);
        }

        public void setUID(int value) //throws Exception
        {
            if (UID().SetterExists())
            {
                UID().Setter(value);
            }
            _base.setUID(value);
        }

        public UUID GetID()
        {
            return _base.GetID();
        }

        public bool IsNew()
        {
            return _base.IsNew();
        }

        public void SetID(UUID id)
        {
            _base.SetID(id);
        }

        public void SetIsNew()
        {
            _base.SetIsNew();
        }


        public void SetIsNotNew() //throws Exception 
        {
            _base.SetIsNotNew();
        }

        public void AddXAttr(IExtendedAttribute attr)
        {
            _base.AddXAttr(attr);
        }

        public LinkedList<IExtendedAttribute> GetAllXAttr()
        {
            return _base.GetAllXAttr();
        }

        public IExtendedAttribute GetXAttr(String name) //throws Exception
        {
            return _base.GetXAttr(name);
        }

        public bool RemoveXAttr(IExtendedAttribute attr) //throws Exception
        {
            return _base.RemoveXAttr(attr);
        }
    }

}
